package com.shiwaixiangcun.authz.web.controller;

import com.alibaba.fastjson.JSON;
import com.shiwaixiangcun.authz.SignUtils;
import com.shiwaixiangcun.authz.dto.VerifyLoginDto;
import com.shiwaixiangcun.authz.service.AccountService;
import com.shiwaixiangcun.core.domain.account.Account;
import com.shiwaixiangcun.core.domain.oauth.AccessToken;
import com.shiwaixiangcun.core.plugin.dto.MonkeyDto;
import com.shiwaixiangcun.core.web.response.MonkeyResponseDto;
import com.shiwaixiangcun.utils.MonkeyUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by SillentWu on 2017/3/2.
 */
@Controller
public class IndexController {
    @Autowired
    private AccountService accountService;

    @Value("${signkey}")
    private String signkey;
    @Value("${shiro.uid.cookie.domain}")
    private String cookieDomain;

    @RequestMapping("")
    public String index() {
        return "redirect:oauth2/platform";
    }

    @ResponseBody
    @RequestMapping(value = "/mi/dynamic/password/message", method = RequestMethod.GET, produces = "application/json; charset=utf-8")
    public String getDynamicPassword(String mobile, String sign) {
        Map<String, String> params = new HashMap<>();
        params.put("mobile", mobile);
        params.put("signkey", signkey);
        if (!SignUtils.verification(params, sign)) {
            MonkeyResponseDto responseDto = new MonkeyResponseDto();
            responseDto.fail(1020, "请求签名失败,请先更新App");
            return JSON.toJSONString(responseDto);
        }
        return JSON.toJSONString(accountService.sendDynamicPasswordMessage(mobile));
    }


    @ResponseBody
    @RequestMapping(value = "/mi/verify/code/password", method = RequestMethod.GET)
    public String getDynamicPassword(String mobile) {
        return JSON.toJSONString(accountService.sendDynamicPasswordMessage(mobile));
    }


    /**
     * 二次验证（API2），包括正常流程和宕机情况
     */

    @ModelAttribute
    @RequestMapping(value = "/mi/login/verify", method = RequestMethod.POST)
    public String verifyLogin(HttpServletRequest request, HttpServletResponse response, VerifyLoginDto verifyLoginDto) {
        Boolean a = accountService.verifyLogin(request, response, verifyLoginDto);
        MonkeyResponseDto responseDto = new MonkeyResponseDto();
        if (a) {
            responseDto.success("验证成功");
            return JSON.toJSONString(responseDto);
        } else {
            responseDto.fail("验证失败");
            return JSON.toJSONString(responseDto);
        }
    }

    /***
     *  获取验证状态码
     * */

    @ModelAttribute
    @RequestMapping(value = "/mi/login/captcha", method = RequestMethod.GET)
    public MonkeyResponseDto startCaptcha(HttpServletRequest request) {
        return new MonkeyResponseDto().success(accountService.startCaptcha(request));
    }


    @ResponseBody
    @RequestMapping(value = "/mi/account", method = RequestMethod.GET, produces = "application/json; charset=utf-8")
    public MonkeyResponseDto getAccount(HttpServletRequest request) {
        return new MonkeyResponseDto().success(accountService.getAccount(AccessToken.getAccessToken(request)));
    }


    @RequestMapping(value = "/mc/current", method = RequestMethod.GET)
    public MonkeyResponseDto getCurrent() {
        Map<String, Object> detailMap = accountService.getAccountUserInfo();
        return new MonkeyResponseDto().success(detailMap);
    }

    @RequestMapping(value = "/mc/modify", method = RequestMethod.PUT)
    public String modify(MonkeyDto monkeyDto) {
        accountService.modifyUserInfo(monkeyDto);
        return "SUCCESS:修改成功";
    }

    @RequestMapping(value = "/mc/setPushAlias", method = RequestMethod.PUT)
    public String setPushAlias(String pushAlias) {
        accountService.setPushAlias(pushAlias);
        return "SUCCESS:操作成功";
    }


    @RequestMapping(value = "/mc/customer/avatar", method = RequestMethod.POST)
    public MonkeyResponseDto uploadAvatar(@RequestParam(name = "file") MultipartFile file) {
        if (file == null) {
            return new MonkeyResponseDto().fail("头像不能为空");
        }
        String accessPath = accountService.uploadHeadImage(file);
        Map<String, String> image = new HashMap<>();
        image.put("avatar", accessPath);
        return new MonkeyResponseDto().success(image);
    }

    @RequestMapping(value = "/mi/h5Login", method = RequestMethod.GET)
    public String h5Login(@RequestParam(name = "redirectURL") String redirectURL, Model model, HttpServletRequest request, HttpServletResponse response) {
        redirectURL = getRedirectURL(redirectURL, request);
        model.addAttribute("redirectURL", redirectURL);
        model.addAttribute("cookieDomain", cookieDomain);
        Cookie[] cookieArr = request.getCookies();
        for (Cookie cookie : cookieArr) {
            if ("access_token".equals(cookie.getName())) {
                cookie.setMaxAge(0);
                cookie.setDomain(cookieDomain);
                cookie.setPath("/");
                response.addCookie(cookie);
            }
        }
        return "h5Login";
    }


    @RequestMapping(value = "/mi/login/verify/code", method = RequestMethod.GET)
    public String verifyCode(HttpServletRequest request, HttpServletResponse response) {
        accountService.verifyCode(request, response);
        return "SUCCESS:成功";
    }

    /**
     * ---------------- 以下代码：处理并获取真实redirectURL-------------
     */

    private String getRedirectURL(String redirectURL, HttpServletRequest request) {
        String[] redirectURLArrary = redirectURL.split("[?]");
        StringBuffer paramsSBF = new StringBuffer();
        if (redirectURLArrary.length > 1) {
            HashMap<String, String> params = getRedirectURLParams(redirectURLArrary[1]);
            Enumeration paramNames = request.getParameterNames();
            while (paramNames.hasMoreElements()) {
                String paramName = (String) paramNames.nextElement();
                if (!"redirectURL".equals(paramName)) {
                    if (isNotExist(params, paramName)) {
                        String[] paramValues = request.getParameterValues(paramName);
                        if (paramValues.length == 1) {
                            paramsSBF.append(paramName).append("=").append(paramValues[0]).append("&");
                        }
                    }
                }
            }
            redirectURL = buildRedirectURL(redirectURL, paramsSBF);
        }
        return redirectURL;
    }

    private String buildRedirectURL(String redirectURL, StringBuffer paramsSBF) {
        if (MonkeyUtils.isNotEmpty(paramsSBF.toString())) {
            if (redirectURL.contains("?")) {
                redirectURL += "&" + paramsSBF.substring(0, paramsSBF.length() - 1);
            } else {
                redirectURL += "?" + paramsSBF.substring(0, paramsSBF.length() - 1);
            }
        }
        return redirectURL;
    }

    private boolean isNotExist(HashMap<String, String> params, String paramName) {
        boolean notExist = true;
        for (Map.Entry<String, String> entry : params.entrySet()) {
            if (paramName.equals(entry.getKey())) {
                notExist = false;
                break;
            }
        }
        return notExist;
    }

    private HashMap<String, String> getRedirectURLParams(String s) {
        String paramStr = s;
        String[] paramKeyValueArray = paramStr.split("[&]");
        HashMap<String, String> params = new HashMap<>();
        for (String paramKeyValue : paramKeyValueArray) {
            String[] param = paramKeyValue.split("[=]");
            if (param.length > 0) {
                params.put(param[0], MonkeyUtils.isNotEmpty(param[1]) ? param[1] : "");
            }
        }
        return params;
    }
}
